#include "../logger/log.h"
#include <thread>
#include <chrono>

void bench(const std::string &logger_name, size_t thread_count, size_t msg_count, size_t msg_len) {
    std::cout << "\t输入线程数量: " << thread_count << " 个" << std::endl;
    std::cout << "\t输出日志数量: " << msg_count << " 条" << std::endl;
    std::cout << "\t输出日志大小: " << msg_count * msg_len / 1024  << " KB" << std::endl;
    // 1.获取日志器
    log::Logger::ptr logger = log::get_logger(logger_name);
    if (logger.get() == nullptr) return;
    // 2.组织指定长度的消息
    std::string msg(msg_len - 1, 'A');
    // 3.创建指定数量的（生产）线程
    std::vector<std::thread> threads;
    std::vector<double> costs(thread_count);
    size_t per_msg_count = msg_count / thread_count;
    for (int i = 0; i < thread_count; i++) {
        threads.emplace_back([&, i](){
            // 4.线程入口函数内部计时开始
            auto start = std::chrono::high_resolution_clock::now();
            // 5.日志消息落地
            for (int j = 0; j < per_msg_count; j++) {
                FATAL_LOG(logger, "%s", msg.c_str());
            }
            // 6.线程入口函数内部计时结束
            auto end = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> cost = end - start;
            costs[i] = cost.count();

            std::cout << "\t线程[" << i << "] 写入的消息数量: " << per_msg_count << " 条 花费时间: " << cost.count() << " s\n"; 
        });
    }
    for (auto &thr : threads) {
        thr.join();
    }
    // 7.计算总耗时
    double total_cost = 0;
    for (int i = 0; i < costs.size(); i++) {
        total_cost = costs[i] > total_cost ? costs[i] : total_cost;
    }
    double msg_per_sec = 1.0 * msg_count / (total_cost);
    double size_per_sec = 1.0 * (msg_count * msg_len) / (total_cost * 1024);
    // 进行输出打印
    std::cout << "\t总消耗时间:" << total_cost << " s\n";
    std::cout << "\t每秒输出日志数量: " << msg_per_sec << " 条\n";
    std::cout << "\t每秒输出日志大小: " << size_per_sec << " KB\n";
}

void sync_bench() {
    static int num = 1;
    std::string logger_name = "sync-logger-" + std::to_string(num);
    std::cout << "------------" << "测试开始" << "------------\n";
    std::cout << "\t同步日志器&单线程\n";
    // <全局同步日志器测试>
    std::unique_ptr<log::LoggerBuilder> builder(new log::GlobalLoggerBuilder);
    builder->build_logger_name(logger_name);
    builder->build_Formatter("[%c]%m%n");
    builder->build_logger_type(log::LoggerType::SYNC_LOGGER);
    builder->build_sink<log::FileLogSink>("./logfile/sync.log");
    builder->build();
    // <全局同步日志器测试>
    bench(logger_name, 1, 1000000, 100);
    
    std::cout << "------------" << "测试结束" << "------------\n";
}
void async_bench(){
    static int num = 1;
    std::string logger_name = "async-logger-" + std::to_string(num);
    std::cout << "------------" << "测试开始" << "------------\n";
    std::cout << "\t异步日志器&多线程\n";
    // <全局异步日志器测试>
    std::unique_ptr<log::LoggerBuilder> builder(new log::GlobalLoggerBuilder);
    builder->build_logger_name(logger_name);
    builder->build_Formatter("[%c]%m%n");
    builder->build_enable_unsafe_async();
    builder->build_logger_type(log::LoggerType::ASYNC_LOGGER);
    builder->build_sink<log::FileLogSink>("./logfile/async.log");
    builder->build();
    // <全局异步日志器测试>
    bench(logger_name, 5, 1000000, 100);
    std::cout << "------------" << "测试结束" << "------------\n";
}
    
int main() {
    for (int i = 0; i < 5; i++) {
        async_bench();
    }
    return 0;
}